#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <setjmp.h>

jmp_buf buf;

// 信号处理函数（实际上不会被调用，因为信号被阻塞了）
void handle_sigint(int signum) {
    printf("Received SIGINT (%d)\n", signum);
    longjmp(buf, 1); // 正常情况下不会执行到这里
}

void handle_sigusr1(int signum) {
    printf("Received SIGUSR1 (%d)\n", signum);
    longjmp(buf, 1); // 正常情况下不会执行到这里
}

int main() {
    sigset_t set;

    // 设置信号处理函数（尽管信号会被阻塞，但还是设置一下以展示如何设置）
    signal(SIGINT, handle_sigint);
    signal(SIGUSR1, handle_sigusr1);

    // 初始化信号集并添加要阻塞的信号
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    sigaddset(&set, SIGUSR1);

    // 阻塞信号
    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
        perror("sigprocmask");
        exit(EXIT_FAILURE);
    }

    // 设置一个跳转点，以便在需要时跳出循环（虽然在这个例子中我们不会用到它）
    if (setjmp(buf) == 0) {
        printf("Signals SIGINT and SIGUSR1 are blocked. Sending signals...\n");

        // 发送5次SIGINT信号
        for (int i = 0; i < 5; i++) {
            kill(getpid(), SIGINT);
            sleep(1); // 等待一秒以分隔信号（仅为了演示目的）
        }

        // 发送5次SIGUSR1信号
        for (int i = 0; i < 5; i++) {
            kill(getpid(), SIGUSR1);
            sleep(1); // 等待一秒以分隔信号（仅为了演示目的）
        }

        printf("Signals sent. Unblocking signals and exiting...\n");

        // 解阻塞信号（虽然在这个例子中我们不会看到任何信号处理函数的输出）
        if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) {
            perror("sigprocmask");
            exit(EXIT_FAILURE);
        }

        // 由于信号被阻塞时不会递送，因此这里不会打印任何由信号处理函数产生的输出
        // 为了演示目的，我们让程序睡眠一段时间，但实际上什么也不会发生
        sleep(10);
    }

    printf("Program exiting normally.\n");
    return 0;
}